package es.udc.fbellas.j2ee.tiendaweb.model.usuariofacade.delegate;

import javax.sql.DataSource;

import es.udc.fbellas.j2ee.tiendaweb.model.direccionpostal.TO.DireccionPostalTO;
import es.udc.fbellas.j2ee.tiendaweb.model.tarjetabancaria.TO.TarjetaBancariaTO;
import es.udc.fbellas.j2ee.tiendaweb.model.usuario.TO.UsuarioProfileTO;
import es.udc.fbellas.j2ee.tiendaweb.model.usuariofacade.TO.LoginResultTO;
import es.udc.fbellas.j2ee.tiendaweb.model.usuariofacade.util.PasswordEncrypter;
import es.udc.fbellas.j2ee.tiendaweb.model.util.GlobalNames;
import es.udc.fbellas.j2ee.util.configuration.ConfigurationParametersManager;
import es.udc.fbellas.j2ee.util.configuration.MissingConfigurationParameterException;
import es.udc.fbellas.j2ee.util.exceptions.InternalErrorException;
import es.udc.fbellas.j2ee.util.sql.DataSourceLocator;
import es.udc.fbellas.j2ee.util.sql.SimpleDataSource;


/**
 * A factory to get <code>UsuarioFacadeDelegate</code> objects.
 * <p>
 * Required configuration parameters:
 * <ul>
 * <li><code>UsuarioFacadeDelegateFactory/delegateClassName</code>: it must 
 * specify the full class name of the class implementing 
 * <code>UsuarioFacadeDelegate</code>.</li>
 * </ul>
 */
public final class UsuarioFacadeDelegateFactory {

    private final static String DELEGATE_CLASS_NAME_PARAMETER =
        "UsuarioFacadeDelegateFactory/delegateClassName";
/*    private final static String USER_FACADE_JNDI_NAME_PARAMETER =
        "UserFacadeDelegateFactory/userFacadeJNDIName";
*/
    private static Class delegateClass;
    //private static String usuarioFacadeJNDIName;

    static {

        try {

            /* DELEGATE_CLASS_NAME_PARAMETER is specified in configuration? */        
            String delegateClassName = 
                ConfigurationParametersManager.getParameter(
                    DELEGATE_CLASS_NAME_PARAMETER);
            delegateClass = Class.forName(delegateClassName);
       
        } catch (MissingConfigurationParameterException e) {

            /* 
             * USER_FACADE_JNDI_NAME_PARAMETER should be specificed in
             * configuration.
             */
/*            try {

                userFacadeJNDIName = 
                       ConfigurationParametersManager.getParameter(
                    USER_FACADE_JNDI_NAME_PARAMETER);

            } catch (MissingConfigurationParameterException e2) {

                e.printStackTrace();
                e2.printStackTrace();
            }
*/
        } catch (Exception e) {
            e.printStackTrace();
        }
       

    }
    
    private UsuarioFacadeDelegateFactory() {}
    
    
    public static UsuarioFacadeDelegate getDelegate() 
        throws InternalErrorException {
        
        try {

//            if (delegateClass != null) {
                return (UsuarioFacadeDelegate) delegateClass.newInstance();
/*            } else {
                return ServiceLocator.findService(UserFacadeDelegate.class,
                    userFacadeJNDIName);
            }*/

        } catch (Exception e) {
            throw new InternalErrorException(e);
        }
        
    }
    
    /* 
     * Test code. Uncomment for testing. Test this class and any class
     * implementing "UsuarioFacadeDelegate".
     */         
    public static void main (String[] args) {
    
        try {

            /* Create a simple data source. */
            DataSource dataSource = new SimpleDataSource();

            /*
             * Add "dataSource" to "DataSourceLocator"
             * (this is needed to test
             * "es.udc.fbellas.j2ee.miniportal.model.userfacade.plain.
             * PlainUserFacadeDelegate"). 
             */
            DataSourceLocator.addDataSource(GlobalNames.TIENDAWEB_DATA_SOURCE,
                dataSource);
                
            /* Create an "UsuarioFacadeDelegate". */
            UsuarioFacadeDelegate delegate =
                UsuarioFacadeDelegateFactory.getDelegate();

System.out.println("\n\n\n");
System.out.println("***************************************************************");
System.out.println("*          PRUEBA DE UNIDAD PARA LA FACHADA USUARIO           *");
System.out.println("***************************************************************");


            /* Test "UsuarioFacadeDelegate::registrarUsuario". */
            System.out.println("\n"+"Test for 'UsuarioFacadeDelegate::registrarUsuario'");
//			try{
				DireccionPostalTO dirPostal1 = new DireccionPostalTO(0, "Fernando", "calle 1", 2, "D",100);
				TarjetaBancariaTO tarjeta1 = new TarjetaBancariaTO(5354, java.sql.Date.valueOf("2009-12-12"));
				UsuarioProfileTO usuario1 = new UsuarioProfileTO("fbella", "myPassword", "Fernando", "Bellas Permuy", "fbellas@udc.es", dirPostal1.getIdDir(), tarjeta1.getNumTarjeta(), "es", "es"); 
            	delegate.registrarUsuario(usuario1, dirPostal1, tarjeta1);
	            System.out.println("User registered" + "\n");
//			}catch(InternalErrorException e){
//				System.out.println("Not done: User already registered" +"\n");
//			}
System.out.println("------------------------------------------------------------------");
            /* Test "UserFacadeDelegate::login". */
            System.out.println("\nTest for 'UsuarioFacadeDelegate::login'");
            LoginResultTO loginResultTO = delegate.login("fbella","myPassword", false);
            System.out.println("Login with clear password successful: " + loginResultTO);
            loginResultTO = delegate.login("fbella", loginResultTO.getEncryptedPassword(), true);
            System.out.println("Login with encrypted password successful: " +
                loginResultTO +"\n");

  
            System.out.println("------------------------------------------------------------------");                                
            /* Test "UserFacadeDelegate::buscarUsuario". */
            System.out.println("\nTest for " + "'UsuarioFacadeDelegate::buscarUsuario'");
            UsuarioProfileTO usuarioProfileTO = delegate.buscarUsuarioProfile();
            System.out.println("User profile: " + usuarioProfileTO +"\n");
System.out.println("------------------------------------------------------------------");
            /* Test "UserFacadeDelegate::buscarDireccionUsuario". */
            System.out.println("\nTest for " + "'UsuarioFacadeDelegate::buscarDireccionUsuario'");
            DireccionPostalTO direccionPostalTO = delegate.buscarDireccionUsuario();
            System.out.println("Direccion Postal del usuario: " + direccionPostalTO +"\n");
System.out.println("------------------------------------------------------------------");
            /* Test "UserFacadeDelegate::buscarTarjetaUsuario". */
            System.out.println("\nTest for " + "'UsuarioFacadeDelegate::buscarTarjetaUsuario'");
            TarjetaBancariaTO tarjetaBancariaTO = delegate.buscarTarjetaUsuario();
            System.out.println("Tarjeta Bancaria del usuario: " + tarjetaBancariaTO +"\n");
System.out.println("------------------------------------------------------------------");
            /* Test "UserFacadeDelegate::updateUserProfile". */
            System.out.println("\nTest for 'UsuarioFacadeDelegate::modificarUsuarioProfile'");
            usuarioProfileTO.setNombre("John");
            usuarioProfileTO.setApellidos("Smith");
            usuarioProfileTO.setEmail("jsmith@acme.com");
            delegate.modificarUsuarioProfile("John", "Smith", "jsmith@acme.com","es","es");
            System.out.println("Updated user profile : " +
                delegate.buscarUsuarioProfile() +"\n");

System.out.println("------------------------------------------------------------------");
            /* Test "UserFacadeDelegate::modificarTarjetaBancaria". */
            System.out.println("\nTest for 'UsuarioFacadeDelegate::modificarTarjetaBancaria'");
            TarjetaBancariaTO tarjeta2 = new TarjetaBancariaTO(5357, java.sql.Date.valueOf("2010-12-3"));
            UsuarioProfileTO usuario2 = delegate.buscarUsuarioProfile();
            delegate.modificarTarjeta(usuario2,tarjeta2);
            System.out.println("Updated user profile : " + delegate.buscarUsuarioProfile() +"\n");

System.out.println("------------------------------------------------------------------");
            /* Test "UserFacadeDelegate::modificarDireccionPostal". */
            System.out.println("\nTest for 'UsuarioFacadeDelegate::modificarDireccionPostal'");
            DireccionPostalTO dir2 = new DireccionPostalTO(0, "Fernando", "caballeros", 67, "D",100);
            UsuarioProfileTO usuario3 = delegate.buscarUsuarioProfile();
            delegate.modificarDireccion(usuario3,dir2);
            System.out.println("Updated user profile : " + delegate.buscarUsuarioProfile() +"\n");

System.out.println("------------------------------------------------------------------");                
            /* Test "UsuarioFacadeDelegate::cambiarPassword". */
            System.out.println("\nTest for " +
                "'UsuarioFacadeDelegate::cambiarPassword'");
            delegate.cambiarPassword("myPassword", "myNewPassword");
            System.out.println("New encrypted password: " + 
                delegate.buscarUsuarioProfile().getEncryptedPassword()+"\n");
System.out.println("------------------------------------------------------------------");
            /* Test "UsuarioFacadeDelegate::cambiarPassword". */
            System.out.println("\nRedo Test for " +
                "'UsuarioFacadeDelegate::cambiarPassword'");
            delegate.cambiarPassword("myNewPassword", "myPassword");
            System.out.println("New encrypted password: " + 
                delegate.buscarUsuarioProfile().getEncryptedPassword() +"\n");
System.out.println("------------------------------------------------------------------");                
//            /* Remove user profile. */
//            System.out.println("Removing user profile");
//            SQLUsuarioProfileDAO dao = SQLUsuarioProfileDAOFactory.getDAO();
//            Connection connection = dataSource.getConnection();
//            dao.remove(connection, "fbellas");
                                    
            /* Tests OK. */
            System.out.println("\t\tTests OK !!!!");

        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }

}
